jQuery.fn.colorize = function(params) {
	options = {
		altColor : '#ECF6FC',// 偶数行颜色，none无色
		bgColor : '#fff',// 背景颜色
		hoverColor : '#BCD4EC',// 鼠标悬停颜色
		hoverClass : '',// 鼠标悬停class
		hiliteColor : 'yellow',
		hiliteClass : '',
		oneClick : false,
		hover : 'row',// 鼠标悬停变色：row行变色，column列变色，cross行列变色
		click : 'row',// 鼠标单击变色：row行变色，column列变色，cross行列变色
		banColumns : [],
		banRows : [],
		banDataClick : false,
		ignoreHeaders : true,// 忽略表头
		nested : false// 是否嵌套
	};
	jQuery.extend(options, params);

	// 颜色处理器
	var colorHandler = {
		// 添加悬停class
		addHoverClass : function() {
			this.origColor = this.style.backgroundColor;
			this.style.backgroundColor = '';
			jQuery(this).addClass(options.hoverClass);
		},
		// 添加背景颜色
		addBgHover : function() {
			this.origColor = this.style.backgroundColor;
			this.style.backgroundColor = options.hoverColor;
		},
		// 移除悬停class
		removeHoverClass : function() {
			jQuery(this).removeClass(options.hoverClass);
			this.style.backgroundColor = this.origColor;
		},
		// 移除背景颜色
		removeBgHover : function() {
			this.style.backgroundColor = this.origColor;
		},
		// 鼠标移入处理
		checkHover : function() {
			if (checkRowBan(this))
				return;
			if (!this.onfire)
				this.hover();// 移入处理
		},
		// 鼠标移出处理
		checkHoverOut : function() {
			if (!this.onfire)
				this.removeHover();// 移出处理
		},
		// 高亮处理
		highlight : function() {
			if (options.hiliteClass.length > 0 || options.hiliteColor != 'none') {
				if (checkRowBan(this))
					return;
				this.onfire = true;

				if (options.hiliteClass.length > 0) {
					this.style.backgroundColor = '';
					jQuery(this).addClass(options.hiliteClass).removeClass(
							options.hoverClass);
				} else if (options.hiliteColor != 'none') {
					this.style.backgroundColor = options.hiliteColor;
					if (options.hoverClass.length > 0)
						jQuery(this).removeClass(options.hoverClass);
				}
			}
		},
		// 取消高亮
		stopHighlight : function() {
			this.onfire = false;
			this.style.backgroundColor = (this.origColor) ? this.origColor : '';
			jQuery(this).removeClass(options.hiliteClass).removeClass(
					options.hoverClass);
		}
	}

	// 列单元格处理
	function processCells(cells, idx, func) {
		var colCells = getColCells(cells, idx);// 列单元格

		jQuery.each(colCells, function(index, cell2) {
			func.call(cell2);
		});

		function getColCells(cells, idx) {
			var arr = [];
			for (var i = 0; i < cells.length; i++) {
				if (cells[i].cellIndex == idx)
					arr.push(cells[i]);
			}
			return arr;
		}
	}

	// 单元格适配器
	function processAdapter(cells, cell, func) {
		processCells(cells, cell.cellIndex, func);
	}

	// 单击处理器
	var clickHandler = {
		// 单击列切换
		toggleColumnClick : function(cells) {
			var func = (!this.onfire) ? colorHandler.highlight : colorHandler.stopHighlight;
			processAdapter(cells, this, func);
		},
		// 单击行切换
		toggleRowClick : function(cells) {
			row = jQuery(this).parent().get(0);
			if (!row.onfire)
				colorHandler.highlight.call(row);
			else
				colorHandler.stopHighlight.call(row);
		},
		// 单击处理
		oneClick : function(clicked) {
			if (clicked != null) {
				if (this.isRepeatClick()) {
					this.stopHilite();
					this.cancel();
				} else {
					this.stopHilite();
					this.hilite();
				}
			} else {
				this.hilite();
			}
		},
		// 列单击处理
		oneColumnClick : function(cells) {
			var indx = this.cellIndex;
			function repeat() {
				return (cells.clicked == indx);
			}
			Column.handleClick(this, cells, indx, repeat);
		},
		// 行单击处理
		oneRowClick : function(cells) {
			var row = jQuery(this).parent().get(0);
			var indx = row.rowIndex;
			function repeat() {
				return (cells.rowClicked == indx);
			}
			Row.handleClick(this, cells, row.rowIndex, repeat);
		},
		// 行列单击处理
		oneColumnRowClick : function(cells) {
			var indx = this.cellIndex;
			var row = jQuery(this).parent().get(0);
			function isRepeatColumn() {
				return (cells.clicked == indx && cells.rowClicked == row.rowIndex);
			}
			function isRepeatRow() {
				return (cells.rowClicked == row.rowIndex && this.cellIndex == cells.clicked);
			}
			Column.handleClick(this, cells, indx, isRepeatColumn);
			Row.handleClick(this, cells, row.rowIndex, isRepeatRow);
		}
	}

	// 列单击处理器
	var Column = {
		// 初始化
		init : function(cell, cells, indx) {
			this.cell = cell;
			this.cells = cells;
			this.indx = indx;
		},
		// 单击处理
		handleClick : function(cell, cells, indx, func) {
			this.init(cell, cells, indx);
			this.isRepeatClick = func;
			clickHandler.oneClick.call(this, cells.clicked);
		},
		// 取消高亮
		stopHilite : function() {
			processCells(this.cells, this.cells.clicked, colorHandler.stopHighlight);
		},
		// 高亮
		hilite : function() {
			processAdapter(this.cells, this.cell, colorHandler.highlight);
			this.cells.clicked = this.indx;
		},
		// 取消单击
		cancel : function() {
			this.cells.clicked = null;
		}
	}

	// 行单击处理器
	var Row = {
		// 初始化
		init : function(cell, cells, indx) {
			this.cell = cell;
			this.cells = cells;
			this.indx = indx;
		},
		// 单击处理
		handleClick : function(cell, cells, indx, func) {
			this.init(cell, cells, indx);
			this.isRepeatClick = func;
			clickHandler.oneClick.call(this, cells.rowClicked);
		},
		// 取消高亮
		stopHilite : function() {
			colorHandler.stopHighlight.call(clickHandler.tbl.rows[this.cells.rowClicked]); // delete
		},
		// 高亮处理
		hilite : function() {
			var row = jQuery(this.cell).parent().get(0);
			if (options.hover == 'column')
				colorHandler.addBgHover.call(row);
			colorHandler.highlight.call(row); // the current row is set to
			this.cells.rowClicked = this.indx; // the current row is recorded
		},
		// 取消
		cancel : function() {
			this.cells.rowClicked = null;
		}
	}

	// 是否数据单元格
	function isDataCell() {
		return (this.nodeName == 'TD');
	}

	// 检查当前列是否在options.banColumns里
	function checkBan() {
		return (jQuery.inArray(this.cellIndex, options.banColumns) != -1);
	}

	// 检查当前行是否在options.banRows里
	function checkRowBan(cell) {
		if (options.banRows.length > 0) {
			var row = jQuery(cell).parent().get(0);
			return jQuery.inArray(row.rowIndex, options.banRows) != -1;
		} else
			return false;
	}

	// 鼠标悬浮处理
	function attachHoverHandler() {
		this.hover = optionsHandler.hover;
		this.removeHover = optionsHandler.removeHover;
	}

	// 鼠标悬停模式：列
	function handleColumnHoverEvents(cell, cells) {
		attachHoverHandler.call(cell);
		// 鼠标移入事件
		cell.onmouseover = function() {
			if (checkBan.call(this))
				return;
			processAdapter(cells, this, colorHandler.checkHover);
		}
		// 鼠标移出事件
		cell.onmouseout = function() {
			if (checkBan.call(this))
				return;
			processAdapter(cells, this, colorHandler.checkHoverOut);
		}
	}

	// 鼠标悬停模式：行
	function handleRowHoverEvents(cell, cells) {
		row = jQuery(cell).parent().get(0);
		attachHoverHandler.call(row);
		row.onmouseover = colorHandler.checkHover;
		row.onmouseout = colorHandler.checkHoverOut;
	}

	// 鼠标悬停模式：行列
	function handleRowColHoverEvents(cell, cells) {
		handleRowHoverEvents(cell, cells);
		handleColumnHoverEvents(cell, cells);
	}

	// 参数处理器
	var optionsHandler = {
		// 设置鼠标悬停class
		setHover : function() {
			if (options.hoverClass.length > 0) {
				this.hover = colorHandler.addHoverClass;
				this.removeHover = colorHandler.removeHoverClass;
			} else {
				this.hover = colorHandler.addBgHover;
				this.removeHover = colorHandler.removeBgHover;
			}
		},
		// 行单元格点击事件
		getRowClick : function() {
			if (options.oneClick)
				return clickHandler.oneRowClick;
			else
				return clickHandler.toggleRowClick;
		},
		// 列单元格点击事件
		getColumnClick : function() {
			if (options.oneClick)
				return clickHandler.oneColumnClick;
			else
				return clickHandler.toggleColumnClick;
		},
		// 行列单元格点击事件
		getRowColClick : function() {
			return clickHandler.oneColumnRowClick;
		}
	}

	// 事件处理器
	var handler = {
		clickFunc : getClickHandler(),
		handleHoverEvents : getHoverHandler()
	};

	// 鼠标悬停处理器
	function getHoverHandler() {
		if (options.hover == 'column')
			return handleColumnHoverEvents;
		else if (options.hover == 'cross')
			return handleRowColHoverEvents;
		else
			return handleRowHoverEvents;
	}

	// 鼠标单击处理器
	function getClickHandler() {
		if (options.click == 'column')
			return optionsHandler.getColumnClick();
		else if (options.click == 'cross')
			return optionsHandler.getRowColClick();
		else
			return optionsHandler.getRowClick();
	}

	return this.each(function() {
		// 设定奇偶数行颜色
		if (options.altColor != 'none') {
			var odd, even;
			odd = even = (options.ignoreHeaders) ? 'tr:has(td)' : 'tr';
			if (options.nested) {
				odd += ':nth-child(odd)';
				even += ':nth-child(even)';
			} else {
				odd += ':odd';
				even += ':even';
			}
			jQuery(this).find(odd).css('background', options.bgColor);// 奇数行颜色
			jQuery(this).find(even).css('background', options.altColor);// 偶数行颜色
		}

//		if (options.columns)
//			alert("The 'columns' option is deprecated.\nPlease use the 'click' and 'hover' options instead.");

		// 获取所有单元格
		if (jQuery(this).find('thead tr:last th').length > 0)
			var cells = jQuery(this).find('td, thead tr:last th');
		else
			var cells = jQuery(this).find('td,th');

		cells.clicked = null;

		if (jQuery.inArray('last', options.banColumns) != -1) {
			if (this.rows.length > 0) {
				options.banColumns.push(this.rows[0].cells.length - 1);
			}
		}

		optionsHandler.setHover();// 设置鼠标悬停颜色
		clickHandler.tbl = this;// 保存当前table实例

		jQuery.each(cells, function(i, cell) {
			handler.handleHoverEvents(this, cells);// 鼠标移入移出事件处理
			$(this).bind("click", function(e) {// 单元格点击事件处理
				if (checkBan.call(this))
					return;
				if (options.banDataClick && isDataCell.call(this))
					return;
				handler.clickFunc.call(this, cells);
			});
		});
	});
}
